#include <iostream>
#include <string>
#include <memory>
#include <ctime>
#include "Socket.hpp"
#include "Protocol.hpp"
#include "InetAddr.hpp"

using namespace socket_ns;
using namespace Protocol_ns;

void Usage(std::string proc)
{
	std::cout << "Usage:\n\t" << proc << " serverip serverport\n"
			  << std::endl;
}

// ./tcp_client serverip serverport
int main(int argc, char *argv[])
{
	if (argc != 3)
	{
		Usage(argv[0]);
		exit(1);
	}
	std::string serverip = argv[1];
	uint16_t serverport = std::stoi(argv[2]);
	InetAddr serveraddr(serverip, serverport);
	Factory factory;
	std::unique_ptr<Socket> client = std::make_unique<TcpSocket>();
	bool res = client->BuildClientSocket(serveraddr);
	std::string inbuffer;

	while (res)
	{
		sleep(1);
		// std::string total_str;
		// for (int i = 0; i < 3; i++)
		// {
		// 	// 1.构建一个请求
		// 	auto req = factory.BuildRequest();

		// 	// 2.对请求进行序列化
		// 	std::string send_str;
		// 	req->Serialize(&send_str);

		// 	std::cout << "Serialize: \n"
		// 			  << send_str << std::endl;

		// 	// 3.添加报头
		// 	send_str = Encode(send_str);
		// 	std::cout << "Encode: \n"
		// 			  << send_str << std::endl;

		// 	total_str += send_str;
		// }

		// 1.构建一个请求
		auto req = factory.BuildRequest();

		// 2.对请求进行序列化
		std::string send_str;
		req->Serialize(&send_str);

		std::cout << "Serialize: \n"
				  << send_str << std::endl;

		// 3.添加报头
		send_str = Encode(send_str);
		std::cout << "Encode: \n"
				  << send_str << std::endl;

		// 4.发送请求
		client->Send(send_str);

		// 5.读取应答

		int n = client->Recv(&inbuffer);
		if (n <= 0)
			break;
		std::string package = Decode(inbuffer);
		if (package.empty())
			break;

		// 6.拿到一个完整的报文，进行反序列化
		auto resp = factory.BuildResponse();
		resp->DeSerialize(package);

		// 7.转化为结构化应答结果
		std::cout << "result:" << resp->_result << "[" << resp->_code << "]" << std::endl;
	}

	return 0;
}